package com.hns.can.mina.handle;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hns.can.base.entity.SysUserRoleEntity;
import com.hns.can.common.constants.GlobalConst;
import com.hns.can.common.service.CacheTaskManager;
import com.hns.can.common.vo.AlarmSettingCacheVo;
import com.hns.can.common.vo.SysCacheVo;
import com.hns.can.mina.enumrate.CanId;
import com.hns.frame.service.CommonService;
import com.hns.tool.pub.PubUtil;

/**
 * 消息推送
 * @author:Fisher
 * @email:zhuangcaijin@126.com
 * @version Revision 2.0.0
 */
@Service
public class PushMsgService extends CommonService {
    
    private static final Logger logger = LoggerFactory.getLogger(PushMsgService.class);
    
    @Autowired
    private CacheTaskManager cacheTaskManager;
    
    private final Calendar cal = Calendar.getInstance();
    
    private final Date date = new Date();
    
    @SuppressWarnings("unchecked")
	public void pushMsg(Map<String, Long> userIdAndSIdMap, 
                Map<Long, IoSession> sIdAndSessionMap, JSONObject oJson) throws Exception {
//        logger.warn("接收报警报文："+oJson.toString());
        String eqmtCd = oJson.get("devId").toString();
        
        if (PubUtil.isNotEmpty(eqmtCd)) {
            // 平台报警
            List<SysUserRoleEntity> list = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("sysUser.getUserRoleByEqmtId", eqmtCd), SysUserRoleEntity.class);
            // 如果不在权限的控制范围不报警
            if (PubUtil.isEmpty(list)) {
                return;
            }
            String data = oJson.get("canId").toString();
            String alarmType = oJson.get("alarmType").toString();
            
//            if (data.equals(CanId.FAULT.getFlag()) && Integer.parseInt(alarmType) < 20) {
//                return;
//            }
            for (SysUserRoleEntity entity : list) {
                Long sId = userIdAndSIdMap.get((entity.getUserId()));
                String corpId = entity.getCorpId();
                if (PubUtil.isEmpty(sId)) {
                    continue;
                }
                IoSession ses = sIdAndSessionMap.get(sId);
                if (PubUtil.isNotEmpty(ses)) {
//                	boolean isPush = checkAlarmPush(oJson, data, alarmType);
                	if(checkAlarmPush(oJson, data, alarmType, corpId))
                		sIdAndSessionMap.get(sId).write("warn");
                }
            }
        }
    }

    /**
     * 校验报警是否推送平台
     * @param oJson
     * @param data
     * @param alarmType
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @author:zhangy
     * @email:zhangyu2222z@sina.cn
     */
	private boolean checkAlarmPush(JSONObject oJson, String data,
			String alarmType, String  corpId) throws InstantiationException,
			IllegalAccessException {
		if(CanId.FAULT.getFlag().equals(data) && checkTimePush(corpId)){
			return checkFaultPush(oJson, alarmType, corpId);
		}else if(CanId.UNSAFEACTION.getFlag().equals(data) && checkTimePush(corpId)){
			return checkUnsafePush(alarmType, corpId);
		}else if(CanId.OVERSPEED.getFlag().equals(data) && checkTimePush(corpId)){
			return checkSpeedPush(oJson, corpId);
		}else
			return false;
	}


	/**
	 * 校验是否发送超速报警
	 * @param oJson
	 * @return
	 * @author:zhangy
	 * @email:zhangyu2222z@sina.cn
	 */
	@SuppressWarnings("unchecked")
	private boolean checkSpeedPush(JSONObject oJson, String corpId) {
		List<AlarmSettingCacheVo> speedSetting = (List<AlarmSettingCacheVo>)cacheTaskManager.loadCache(
				GlobalConst.CACHE_ALARM_SPEED_SETTING, corpId);
		if(PubUtil.isNotEmpty(speedSetting)){
			if(PubUtil.isEmpty(oJson.get("limitSpeed")))
				return false;
			double limitSpeed = Double.parseDouble(oJson.get("limitSpeed").toString());
			double averageSpeed = Double.parseDouble(oJson.get("averageSpeed").toString());
			double perVal = (averageSpeed-limitSpeed)*100/limitSpeed;
//			logger.warn("速度"+perVal+", 设置："+speedSetting.get(0).getValue());
			if(perVal>0 && perVal <= 10 && '1' == speedSetting.get(0).getValue().charAt(2))
				return true;
			if(perVal>10 && perVal <= 20 && '1' == speedSetting.get(0).getValue().charAt(1))
				return true;
			if(perVal>20 && perVal <= 1000 && '1' == speedSetting.get(0).getValue().charAt(0))
				return true; 
			else  
				return false; 
		}else{
			return true;
		}
	}


	/**
	 * 校验是否发送不安全行为报警
	 * @param alarmType
	 * @return
	 * @author:zhangy
	 * @email:zhangyu2222z@sina.cn
	 */
	@SuppressWarnings("unchecked")
	private boolean checkUnsafePush(String alarmType, String corpId) {
		List<AlarmSettingCacheVo> unsafeSetting = (List<AlarmSettingCacheVo>)cacheTaskManager.loadCache(
				GlobalConst.CACHE_ALARM_UNSAFE_SETTING, corpId);
//		logger.warn("不安全行为编号："+alarmType+"，不安全行为设置："+unsafeSetting.get(0).getValue());
		if(PubUtil.isNotEmpty(unsafeSetting)){
			if(Integer.parseInt(alarmType) > unsafeSetting.get(0).getValue().length()){
				return false;
			}else
				return ('1'==unsafeSetting.get(0).getValue().charAt(Integer.parseInt(alarmType)-1));
		}else
			return true;
	}

	
	/**
	 * 校验是否发送故障报警
	 * @param oJson
	 * @param alarmType
	 * @return
	 * @author:zhangy
	 * @email:zhangyu2222z@sina.cn
	 */
	@SuppressWarnings("unchecked")
	private boolean checkFaultPush(JSONObject oJson, String alarmType, String corpId) {
		List<AlarmSettingCacheVo> faultSetting = (List<AlarmSettingCacheVo>)cacheTaskManager.loadCache(
				GlobalConst.CACHE_ALARM_FAULT_SETTING, corpId);
//		logger.warn("faultSetting："+faultSetting+"，faultSetting length："+faultSetting.size());
		if(!PubUtil.isEmpty(faultSetting)){
			String malTabType = oJson.get("malTabType").toString();
//			logger.warn("企业id："+corpId+"，故障编号："+alarmType+"，区分代码："+malTabType);
			for(AlarmSettingCacheVo vo : faultSetting){
//				logger.warn(vo.getMftType()+"，故障编号对照："+alarmType+"，"+vo.getMftDiscCode()+"，区分代码对照："+malTabType);
				if(malTabType.equals(vo.getMftDiscCode()) && alarmType.equals(vo.getMftType()) && corpId.equals(vo.getCorpId())){
//					logger.warn("++++++++++++不下发");
					return false;
				}
			}
//			logger.warn("---------------下发");
			return true;
		}else
			return true;
	}


	/**
	 * 检验发送报警时间
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @author:zhangy
	 * @email:zhangyu2222z@sina.cn
	 */
	@SuppressWarnings("unchecked")
	private boolean checkTimePush(String corpId)
			throws InstantiationException, IllegalAccessException {
		//时间过滤
		List<AlarmSettingCacheVo> timeSetting = (List<AlarmSettingCacheVo>)cacheTaskManager.loadCache(
				GlobalConst.CACHE_ALARM_TIME_SETTING, corpId);
		if(PubUtil.isEmpty(timeSetting)){
			return true;
		}
		cal.setTime(date);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 2;
		if(w<0) w=6;
		StringBuffer timeStr = StringBuffer.class.newInstance().append(cal.get(Calendar.HOUR_OF_DAY))
				.append(":").append(cal.get(Calendar.MINUTE));
		if(checkAlarmTime(timeSetting.get(0), w, timeStr.toString(), 1) || checkAlarmTime(timeSetting.get(0), w, timeStr.toString(), 2)
				||checkAlarmTime(timeSetting.get(0), w, timeStr.toString(), 3)){
			return true;
		}else
			return false;
	}
    
    /**
     * 报警时间校验
     * @param vo
     * @param num
     * @param timeStr
     * @param sort
     * @return
     * @author:zhangy
     * @email:zhangyu2222z@sina.cn
     */
    @SuppressWarnings("rawtypes")
	private boolean checkAlarmTime(AlarmSettingCacheVo vo, int num, String timeStr, int sort) {
    	
    	Class[] clazzs = null;
    	Object[] objs = null;
		try {
			Method weekMethod = vo.getClass().getMethod("getTimeWeek"+sort, clazzs);
			Object week = weekMethod.invoke(vo, objs);
			Method timeStartMethod = vo.getClass().getMethod("getTimeStart"+sort, clazzs);
			Object startTime = timeStartMethod.invoke(vo, objs);
			Method timeEndMethod = vo.getClass().getMethod("getTimeEnd"+sort, clazzs);
			Object endTime = timeEndMethod.invoke(vo, objs);
			if(PubUtil.isEmpty(week) || PubUtil.isEmpty(startTime) || PubUtil.isEmpty(endTime)){
				return false;
			}
//			logger.warn(num+",星期设置："+week.toString()+"，开始时间："+startTime.toString()+"，结束时间："+endTime.toString());
			if(PubUtil.isEmpty(week) || week.toString().charAt(num)!='1')//是否符合星期
				return false;
			if(PubUtil.isEmpty(startTime) || timeStr.compareTo(startTime.toString())<0)//是否低于报警开始时间
				return false;
			if(PubUtil.isEmpty(endTime) || timeStr.compareTo(endTime.toString())>0)//是否超过报警结束时间
				return false;
//			logger.warn("========================================================");
			return true;
		} catch (NoSuchMethodException | SecurityException | IllegalAccessException 
				| IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
			return false;
		}
    }
    
}
